package com.chushouya.order.service.api.impl;

import com.chushouya.order.rabbitmq.sender.DangDangOrderMessageSender;
import com.general.framework.core.lang.*;
import com.chushouya.common.support.Contexts;
import com.chushouya.common.util.RabbitMQUtil;
import com.general.framework.core.enums.DelFlagEnum;
import com.general.framework.core.exception.Ex;
import com.general.framework.data.redis.RedisLock;
import com.chushouya.manager.dao.entity.PartnerEntity;
import com.chushouya.manager.dao.entity.RegionEntity;
import com.chushouya.manager.service.common.PartnerApiService;
import com.chushouya.manager.service.common.RegionService;
import com.chushouya.order.constants.BizTypeEnum;
import com.chushouya.order.constants.OrderStatusEnum;
import com.chushouya.order.constants.OrderTypeEnum;
import com.chushouya.order.dao.entity.OrderClothesProductEntity;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.entity.OrderAddressEntity;
import com.chushouya.order.dao.entity.OrderExtendEntity;
import com.chushouya.order.dao.repository.OrderClothesProductRepository;
import com.chushouya.order.dao.repository.OrderRepository;
import com.chushouya.order.dao.repository.OrderAddressRepository;
import com.chushouya.order.dao.repository.OrderExtendRepository;
import com.chushouya.order.dto.api.order.OrderAddressApiDTO;
import com.chushouya.order.dto.api.order.OrderUserApiDTO;
import com.chushouya.order.dto.api.orderclothesproduct.OrderClothesSubmitDTO;
import com.chushouya.order.dto.mq.promote.PromoteMqDTO;
import com.chushouya.common.constant.RabbitMqQueueEnum;
import com.chushouya.order.rabbitmq.sender.NotifyMessageSender;
import com.chushouya.order.service.api.OrderClothesSubmitApiService;
import com.chushouya.product.dao.entity.ClothesProductEntity;
import com.chushouya.product.service.common.ClothesProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 旧衣订单提交API服务实现
 */
@Service
@Slf4j
public class OrderClothesSubmitApiServiceImpl implements OrderClothesSubmitApiService {

    @Resource
    private OrderClothesProductRepository orderClothesProductRepository;

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private OrderAddressRepository orderAddressRepository;

    @Resource
    private OrderExtendRepository orderExtendRepository;

    @Resource
    private PartnerApiService partnerApiService;

    @Resource
    private RabbitMQUtil rabbitMQUtil;

    @Resource
    private RedisLock redisLock;

    @Resource
    private NotifyMessageSender notifyMessageSender;

    @Resource
    private ClothesProductService clothesProductService;

    @Resource
    private RegionService regionService;

    @Resource
    private DangDangOrderMessageSender dangDangOrderMessageSender;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderUserApiDTO createOrder(OrderClothesSubmitDTO submitDTO) {
        log.info("创建旧衣订单开始，参数：{}", Jsons.toJsonString(submitDTO));
        
        // 1. 创建分布式锁，防止重复提交
        final String lockKey = Strings.format("clothes_order_submit_lock:{}", Contexts.getUserContext().getUserId());
        boolean lockAcquired = redisLock.tryLock(lockKey, 5L, TimeUnit.SECONDS);
        if (!lockAcquired) {
            log.error("旧衣订单提交过于频繁：{}", Jsons.toJsonString(submitDTO));
            throw Ex.business("操作频繁，请稍后再试");
        }

        try {
            // 2. 获取用户上下文
            Long userId = Contexts.getUserContext().getUserId();
            if (Longs.isNullOrZero(userId)) {
                throw Ex.business("用户未登录");
            }

            // 3. 验证订单数据
            validateOrderData(submitDTO);

            // 4. 创建订单数据
            return createOrderData(submitDTO, userId);
        } finally {
            // 只有成功获取锁的情况下才释放锁
            if (lockAcquired) {
                redisLock.unlock(lockKey);
            }
        }
    }

    /**
     * 验证订单数据
     */
    private void validateOrderData(OrderClothesSubmitDTO submitDTO) {
        // 验证预约时间
        if (Objects.isNull(submitDTO.getAppointStartTime()) || Objects.isNull(submitDTO.getAppointEndTime())) {
            throw Ex.business("预约时间不能为空");
        }

        // 验证地址信息
        if (Objects.isNull(submitDTO.getAddressInfo())) {
            throw Ex.business("地址信息不能为空");
        }
    }

    /**
     * 创建订单数据
     */
    @Transactional
    public OrderUserApiDTO createOrderData(OrderClothesSubmitDTO submitDTO, Long userId) {
        OrderUserApiDTO orderUserApiDTO = new OrderUserApiDTO();
        final Long partnerId = Contexts.getHeaderContext().getPartnerId();
        log.info("提交旧衣订单，用户ID：{}，合作商ID：{}", userId, partnerId);
        final String platform = Contexts.getHeaderContext().getPlatform();
        final String appId = Contexts.getHeaderContext().getAppId();
        final String channel = submitDTO.getChannel();

        PartnerEntity partnerEntity = getPartnerInfo(partnerId);
        
        log.info("开始创建旧衣订单");

        // 1. 生成系统订单号
        String orderNo = generateOrderNo();

        final OrderAddressApiDTO orderAddressApiDTO = submitDTO.getAddressInfo();
        final String userName = orderAddressApiDTO.getUserName();
        final String userPhone = orderAddressApiDTO.getUserPhone();

        // 2. 根据地区编码获取商品信息
        Long districtCode = orderAddressApiDTO.getDistrictCode();
        RegionEntity regionEntity = regionService.getRegionByCode(districtCode);
        if (Objects.isNull(regionEntity)) {
            throw Ex.business("区域信息不存在，区县编码：{}" , districtCode);
        }
        ClothesProductEntity clothesProduct = clothesProductService.getProductByCode(regionEntity.getProvinceCode());
        
        // 3. 创建订单实体
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderNo(orderNo);
        orderEntity.setUserId(userId);
        orderEntity.setUserName(userName);
        orderEntity.setUserPhone(userPhone);
        
        // 设置商品信息
        if (Objects.nonNull(clothesProduct)) {
            orderEntity.setProductId(clothesProduct.getClothesProductId());
            orderEntity.setProductName(clothesProduct.getProductName());
            orderEntity.setProductImage(Strings.defaultString(clothesProduct.getProductImage(), ""));
            log.info("根据地区编码{}获取到商品信息：{}", districtCode, clothesProduct.getProductName());
        } else {
            orderEntity.setProductId(0L);
            orderEntity.setProductName("旧衣回收");
            orderEntity.setProductImage("");
            log.warn("未找到地区编码{}对应的旧衣商品信息，使用默认值", districtCode);
        }
        
        // 设置订单状态和类型
        orderEntity.setOrderStatus(OrderStatusEnum.NEW_ORDER.value()); // 待确认
        orderEntity.setOrderType(OrderTypeEnum.EXPRESS_RECYCLE.value()); // 旧衣订单类型
        orderEntity.setOrderSource(0); // 官方
        orderEntity.setBizType(BizTypeEnum.JIUYI.value()); // 旧衣业务类型

        // 设置价格信息
        orderEntity.setEvaluatePrice(BigDecimal.ZERO);
        orderEntity.setQualityPrice(BigDecimal.ZERO);
        orderEntity.setBonusPrice(BigDecimal.ZERO);
        orderEntity.setOrderPrice(BigDecimal.ZERO);
        orderEntity.setCompletePrice(BigDecimal.ZERO);
        
        // 设置支付状态
        orderEntity.setPayType(0);
        orderEntity.setPayStatus(0); // 未支付
        orderEntity.setPrepaidStatus(0);
        orderEntity.setLogisticsStatus(-1); // 无物流
        
        // 设置时间信息
        Date now = Dates.getTimeNow();
        orderEntity.setCreateTime(now);
        orderEntity.setUpdateTime(now);
        orderEntity.setAppointStartTime(submitDTO.getAppointStartTime());
        orderEntity.setAppointEndTime(submitDTO.getAppointEndTime());

        // 设置渠道和平台信息
        orderEntity.setPartnerId(partnerEntity.getPartnerId());
        orderEntity.setPartnerName(partnerEntity.getPartnerName());
        orderEntity.setPlatform(platform);
        orderEntity.setChannel(Strings.defaultString(channel, Strings.EMPTY));
        
        // 设置备注
        orderEntity.setOrderRemark(submitDTO.getRemark());
        orderEntity.setAppId("");
        
        // 3. 保存订单
        orderRepository.insertSelective(orderEntity);
        Long orderId = orderEntity.getOrderId();

        log.info("旧衣订单创建成功，订单ID：{}，订单号：{}", orderId, orderNo);
        
        // 4. 保存订单地址信息
        createOrderAddress(orderId, userId, submitDTO,regionEntity);
        
        // 5. 保存旧衣商品订单信息
        createOrderClothesProduct(orderId, submitDTO, clothesProduct);
        
        // 6. 保存订单扩展信息
        createOrderExtend(orderId, submitDTO);

        // 7. 执行订单创建后的处理（异步）
        handleOrderAfter(orderEntity, submitDTO);
        
        orderUserApiDTO.setOrderNo(orderNo);
        return orderUserApiDTO;
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        String timestamp = Dates.format(Dates.getTimeNow(), "yyyyMMddHHmmss");
        String random = String.format("%04d", (int)(Math.random() * 10000));
        return "CL" + timestamp + random;
    }

    /**
     * 获取渠道信息
     */
    private PartnerEntity getPartnerInfo(Long partnerId) {
        if (Longs.isNullOrZero(partnerId)) {
            // 如果没有合作商ID，使用默认值
            PartnerEntity defaultPartner = new PartnerEntity();
            defaultPartner.setPartnerId(1L);
            defaultPartner.setPartnerName("官方");
            return defaultPartner;
        }
        PartnerEntity partnerEntity = partnerApiService.getPartnerInfo(partnerId);
        if (Objects.isNull(partnerEntity)) {
            throw Ex.business("渠道信息不存在");
        }
        return partnerEntity;
    }

    /**
     * 创建订单地址信息
     */
    private void createOrderAddress(Long orderId, Long userId, OrderClothesSubmitDTO submitDTO, RegionEntity regionEntity) {
        final OrderAddressApiDTO addressApiDTO = submitDTO.getAddressInfo();
        if (Objects.nonNull(addressApiDTO)) {
            OrderAddressEntity orderAddressEntity = Beans.copy(regionEntity, OrderAddressEntity.class);
            orderAddressEntity.setOrderId(orderId);
            orderAddressEntity.setUserId(userId);
            orderAddressEntity.setUserName(addressApiDTO.getUserName());
            orderAddressEntity.setUserPhone(addressApiDTO.getUserPhone());
            orderAddressEntity.setAddress(addressApiDTO.getAddress());
            orderAddressEntity.setCreateTime(Dates.getTimeNow());
            orderAddressEntity.setUpdateTime(Dates.getTimeNow());
            orderAddressRepository.insertSelective(orderAddressEntity);
        }
    }

    /**
     * 创建旧衣商品订单信息
     */
    private void createOrderClothesProduct(Long orderId, OrderClothesSubmitDTO submitDTO, ClothesProductEntity clothesProduct) {
        log.info("创建旧衣商品订单信息，订单ID：{}", clothesProduct.getProductPrice());
        OrderClothesProductEntity clothesProductEntity = Beans.copy(clothesProduct, OrderClothesProductEntity.class);
        clothesProductEntity.setOrderId(orderId);
        clothesProductEntity.setWeightRange(submitDTO.getWeightRange());
        clothesProductEntity.setStatus(OrderStatusEnum.NEW_ORDER.value()); // 待处理状态
        
        // 设置商品信息
        if (Objects.isNull(clothesProduct)) {
            throw Ex.business("未找到对应的旧衣商品信息");
        }
            clothesProductEntity.setProvinceCode(clothesProduct.getProvinceCode());
            clothesProductEntity.setProvince(clothesProduct.getProvince());
            clothesProductEntity.setProductName(clothesProduct.getProductName());

        
        clothesProductEntity.setCreateTime(Dates.getTimeNow());
        clothesProductEntity.setUpdateTime(Dates.getTimeNow());
        clothesProductEntity.setDelFlag(DelFlagEnum.normal.getValue());
        
        orderClothesProductRepository.insertSelective(clothesProductEntity);
    }

    /**
     * 创建订单扩展信息
     */
    private void createOrderExtend(Long orderId, OrderClothesSubmitDTO submitDTO) {
        if (Objects.nonNull(submitDTO.getExtendInfo())) {
            OrderExtendEntity orderExtendEntity = Beans.copy(submitDTO.getExtendInfo(), OrderExtendEntity.class);
            orderExtendEntity.setOrderId(orderId);
            orderExtendEntity.setCreateTime(Dates.getTimeNow());
            orderExtendEntity.setUpdateTime(Dates.getTimeNow());
            orderExtendRepository.insertSelective(orderExtendEntity);
        }
    }

    /**
     * 订单创建后的处理
     */
    private void handleOrderAfter(OrderEntity orderEntity, OrderClothesSubmitDTO submitDTO) {
        // 1. 给用户发送短信通知
        handleSendUserNotify(orderEntity);
        // 2. 处理合作商推广标签
        handlePartnerPromoteLabel(orderEntity, submitDTO);
        // 3. 发送铛铛订单处理消息
        handleDangdangManager(orderEntity);
        
        log.info("旧衣订单后续处理完成，订单ID：{}", orderEntity.getOrderId());
    }

    /**
     * 处理铛铛订单管理
     */
    private void handleDangdangManager(OrderEntity orderEntity) {
        dangDangOrderMessageSender.sendDangDangOrderMessage(
            orderEntity.getOrderId(),
            "DANGDANG_ORDER_CREATE",5L, TimeUnit.SECONDS
        );
    }

    /**
     * 给用户发送短信通知
     */
    private void handleSendUserNotify(OrderEntity orderEntity) {
        final Long orderId = orderEntity.getOrderId();
        notifyMessageSender.sendSmsNotifyMessage(orderId);
    }

    /**
     * 处理合作商推广标签
     */
    private void handlePartnerPromoteLabel(OrderEntity orderEntity, OrderClothesSubmitDTO submitDTO) {
        final String promoteLabel = submitDTO.getChannel();
        final Long orderId = orderEntity.getOrderId();
        if (Strings.isEmpty(promoteLabel)) {
            return;
        }
        // 调用队列
        PromoteMqDTO promoteMqDTO = new PromoteMqDTO();
        promoteMqDTO.setOrderId(orderId);
        promoteMqDTO.setPromoteLabel(promoteLabel);
        rabbitMQUtil.sendMessage(RabbitMqQueueEnum.PROMOTE_LABEL.getQueueName(), promoteMqDTO);
    }
}
